package com.android.studyspot;

import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.microsoft.windowsazure.mobileservices.MobileServiceClient;
import com.microsoft.windowsazure.mobileservices.MobileServiceTable;
import com.microsoft.windowsazure.mobileservices.ServiceFilterResponse;
import com.microsoft.windowsazure.mobileservices.TableDeleteCallback;
import com.microsoft.windowsazure.mobileservices.TableOperationCallback;
import com.microsoft.windowsazure.mobileservices.TableQueryCallback;

import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class AddCoursesActivity extends SherlockActivity {
	private Bundle hashmap;
	private Spinner deptSpinner;
	private Spinner crsNumSpinner;
	private ArrayList<String> deptList;
	private MobileServiceClient mClient;
	private MobileServiceTable<vw_distinct_courseabbrev> mCourseAbbrevView;
	private MobileServiceTable<courses> mCourseTable;
	private MobileServiceTable<users> mUsersTable;
	private MobileServiceTable<user_course> mUserCourseTable;
	private MobileServiceTable<vw_users_uc_courses> mUsersCoursesView;
	private ArrayList<String> courseNumList;
	private ListView coursesListView;
	private Button addCourseButton;
	private ArrayList<String> courseList;
	private CustomAdapter courseAdapter;
	private com.actionbarsherlock.view.ActionMode.Callback mActionModeCallback;
	private com.actionbarsherlock.view.ActionMode mActionMode;
	private int position;
	private int userId;
	private Menu addCoursesMenu;
	private users user;
	private Typeface typeFace;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		typeFace = Typeface.createFromAsset(getAssets(),"fonts/futuraCondensed.ttf");
		
		deptList = new ArrayList<String>();
		courseList = new ArrayList<String>();
		
		hashmap = this.getIntent().getExtras();
		
		// Connect to Study Spot Azure Mobile Service
		try {
			mClient = new MobileServiceClient(
				      "https://studyspot.azure-mobile.net/",
				      "UeeXTmfsscRIhhVuCyRqDRwfThBDPa90",
				      this
			);
			
			this.mCourseAbbrevView = mClient.getTable(vw_distinct_courseabbrev.class);
			this.mCourseTable = mClient.getTable(courses.class);
			this.mUserCourseTable = mClient.getTable(user_course.class);
			this.mUsersCoursesView = mClient.getTable(vw_users_uc_courses.class);
			
			// Ask Janzen why we need to run garbage collector before inflating
			// Something to do with image sizes and bitmaps
			System.gc();
			
			initLayout();
			
			// Call method that creates dept. and course num. dropdowns
			populateSpinners();
			
			populateList();
			
			setAddCourseListener();
			
		}
		catch (MalformedURLException e) {
			Log.d("Azure", e.getMessage());
			e.printStackTrace();
		}
		
	}
	
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.add_courses_menu, menu);
        this.addCoursesMenu = menu;
        return true;
    }
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			case R.id.add_courses_save:
				Intent userProfileStart = new Intent(AddCoursesActivity.this, UserProfileActivity.class);
				userProfileStart.putExtra("userId", hashmap.getInt("userId"));
				startActivity(userProfileStart);
				return true;
			default:
				return true;
		}
	}
	
	// Initializes the layout and widgets
	private void initLayout() {
		setContentView(R.layout.layout_add_courses);
		
		this.coursesListView = (ListView)this.findViewById(R.id.course_list_view);
		this.coursesListView.setLongClickable(true);
		
		courseAdapter = new CustomAdapter(this, R.layout.list_item, courseList, typeFace);
		this.coursesListView.setAdapter(courseAdapter);
		
		deptSpinner = (Spinner)findViewById(R.id.dept_spinner);
		crsNumSpinner = (Spinner)findViewById(R.id.course_num_spinner);
		
		// Create Callback that inflates the delete menu and handles course deletion
		this.mActionModeCallback = new ActionMode.Callback() {
			
			@Override
			public boolean onPrepareActionMode(ActionMode mode,
					com.actionbarsherlock.view.Menu menu) {
	
				return false;
			}
			
			@Override
			public void onDestroyActionMode(ActionMode mode) {
				mActionMode = null;
				
			}
			
			@Override
			public boolean onCreateActionMode(ActionMode mode,
					com.actionbarsherlock.view.Menu menu) {
				MenuInflater inflater = mode.getMenuInflater();
				inflater.inflate(R.menu.actionmenu, menu);
				return true;
			}
			
			@Override
			public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
				switch (item.getItemId()) {
				case R.id.menu_remove:
					removeCourseFromDb(position);
					courseList.remove(position);
					courseAdapter.notifyDataSetChanged();
					mode.finish();
					return true;
				default:
					return false;
				}
			}
			
			private void removeCourseFromDb(int position) {				
				mCourseTable.where().field("course").eq(courseList.get(position))
				.execute(new TableQueryCallback<courses>() {

					@Override
					public void onCompleted(List<courses> result, int count,
							Exception exception, ServiceFilterResponse response) {
						int userId;
						int courseId;
						if (exception == null) {
							userId  = hashmap.getInt("userId");
							
							courseId = result.get(0).id;
							
							mUserCourseTable.where().field("uc_userid").eq(userId).and().field("uc_courseid").eq(courseId)
							.execute(new TableQueryCallback<user_course>() {

								@Override
								public void onCompleted(List<user_course> result,
										int count, Exception exception,
										ServiceFilterResponse response) {
									if (exception == null) {
										for (user_course item : result) {
											mUserCourseTable.delete(item.id, new TableDeleteCallback() {
												@Override
												public void onCompleted(Exception exception,
														ServiceFilterResponse response) {
													if (exception == null) {
														Log.d("StudySpot", "Successfully deleted course");
													}
													else {
														Log.e("StudySpot", exception.getMessage());
													}
												}			
											});
										}
									}
									else {
										Log.e("StudySpot", exception.getMessage());
									}
									
								}
								
							});
						}
						else {
							Log.e("StudySpot", exception.getMessage());
						}
						
					}
					
				});
				
			}
		};
		
		// Prompts user to remove course from added courses list when it is long clicked
		this.coursesListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				if (mActionMode != null) {
		            return false;
		        }
				
				position = arg2;

		        // Start the CAB using the ActionMode.Callback defined above
		        mActionMode = getSherlock().startActionMode(mActionModeCallback);
		        arg1.setSelected(true);
		        return true;
			}
		});
		
		setFont();
	}
	
	private void setFont() {
		TextView label;
		
		label = (TextView)this.findViewById(R.id.dept_label);
		label.setTypeface(typeFace);
		
		label = (TextView)this.findViewById(R.id.course_num_label);
		label.setTypeface(typeFace);
		
	}
	
	private void addCourseToDb(String course) {
		this.mCourseTable.where().field("course").eq(course)
		.execute(new TableQueryCallback<courses>() {

			@Override
			public void onCompleted(List<courses> result, int count,
					Exception exception, ServiceFilterResponse response) {
				user_course uc;
					
				if (exception == null) {
					uc = new user_course();
					uc.uc_userid = hashmap.getInt("userId");
					uc.uc_courseid = result.get(0).id;
						
					mUserCourseTable.insert(uc, new TableOperationCallback<user_course>() {

						@Override
						public void onCompleted(user_course entity,
								Exception exception, ServiceFilterResponse response) {
							if (exception == null) {
								Log.d("StudySpot", "user_course " + entity.id + " successfully added");
							}
							else {
								Log.e("StudySpot", exception.getMessage());
							}
						}
					});
				}
				else {
					Log.e("StudySpot", exception.getMessage());
				}
			}
		});
	}
	
	private void populateList() {
		this.mUsersCoursesView.where().field("usr_id").eq(hashmap.getInt("userId"))
		.execute(new TableQueryCallback<vw_users_uc_courses>() {

			@Override
			public void onCompleted(List<vw_users_uc_courses> result, int count,
					Exception exception, ServiceFilterResponse response) {
				if (exception == null) {
					for (vw_users_uc_courses item : result) {
						courseList.add(item.course);
					}
					courseAdapter.notifyDataSetChanged();
				}
				else {
					Log.e("StudySpot", exception.getMessage());
				}
				
			}
			
		});
	}
	
	// Listener for the add course "+" button
	private void setAddCourseListener() {
		this.addCourseButton = (Button)this.findViewById(R.id.add_course_button);
		
		this.addCourseButton.setOnClickListener(new OnClickListener() {
			String course;
			
			@Override
			public void onClick(View v) {
				course = deptSpinner.getSelectedItem().toString() + " " + crsNumSpinner.getSelectedItem().toString();
				if (courseList.contains(course)) {
					Toast toast = Toast.makeText(AddCoursesActivity.this, course + " Already Added", Toast.LENGTH_LONG);
					toast.show();
				}
				else {
					addCourseToDb(course);
					addCourse(course);
				}
			}
			
		});
	}
	
	// Adds course to list view
	private void addCourse(String course) {
		this.courseList.add(course);
		this.courseAdapter.notifyDataSetChanged();
	}
	
	// Populates the values for the department and course number spinners by querying the database
	private void populateSpinners() {
		
		// Query that gets all distinct department abbreviations for Cal Poly (School ID = 1)
		this.mCourseAbbrevView.where().field("crs_school_id").eq(1)
		.execute(new TableQueryCallback<vw_distinct_courseabbrev>() {
			@Override
			public void onCompleted(List<vw_distinct_courseabbrev> result, 
                                  int count, 
                                  Exception exception,
                                  ServiceFilterResponse response) {
				// Query was successful
				if (exception == null) {
					for (vw_distinct_courseabbrev item : result) {  
						deptList.add(item.crsabbrev);
					}
      
					// Department spinner is filled with values from above query
					ArrayAdapter<String> abbrevAdapter = new ArrayAdapter<String>(AddCoursesActivity.this, R.layout.sherlock_spinner_item, deptList);
					abbrevAdapter.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);
					deptSpinner.setAdapter(abbrevAdapter);
					
					setSpinnerListener();
			} 
			else {
				Log.d("Query", exception.getMessage());
			}
		}
	});
	}
	
	// Sets listener for dept. spinner.  Also dynamically populates values for course num spinner
	private void setSpinnerListener() {
		// Creates listener that triggers when item is selected from dept. spinner dropdown
		deptSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> parent,
					View view, int pos, long id) {
			
			courseNumList = new ArrayList<String>();
			String abbrev = parent.getItemAtPosition(pos).toString();
			
			// Run query that gets all course numbers offered by the department selected from dept. spinner
			mCourseTable.where().field("crsabbrev").eq(abbrev)
				.execute(new TableQueryCallback<courses>() {
					@Override
					public void onCompleted(
							List<courses> result, int count,
							Exception exception,
							ServiceFilterResponse response) {
						// Query was successful
						if (exception == null) {
							for (courses item : result) {
								courseNumList.add(item.crsnum);
							}
							
							// Course Number spinner is filled with values from above query
							ArrayAdapter<String> crsNumAdapter = new ArrayAdapter<String>(AddCoursesActivity.this, R.layout.sherlock_spinner_item, courseNumList);
							crsNumAdapter.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);
							crsNumSpinner.setAdapter(crsNumAdapter);
						}	
					}	
				});		
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				// TODO Auto-generated method stub
				
			}
		});
	}
}
